package com.buleqr.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.buleqr.dao.CouponCodeDao;
import com.buleqr.dao.UserCouponCodeDao;
import com.buleqr.dao.UserDao;
import com.buleqr.dto.request.CouponQuery;
import com.buleqr.dto.request.UserCouponCodeQuery;
import com.buleqr.dto.request.UserCouponCodeReq;
import com.buleqr.dto.response.CouponCodeVo;
import com.buleqr.dto.response.UserCouponCodeVo;
import com.buleqr.pojo.*;
import com.buleqr.service.IUserCouponCodeService;
import lombok.AllArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;


@Service
@AllArgsConstructor
public class UserCouponCodeServiceImpl implements IUserCouponCodeService {

    private final UserCouponCodeDao baseDao;

    private final CouponCodeDao couponCodeDao;

    private final UserDao userDao;

    private final RedisTemplate redisTemplate;

    private final ModelMapper modelMapper;

    @Override
    public AjaxResult add(UserCouponCodeReq req) {
        Object o = redisTemplate.opsForValue().get("user_coupon_code_add:" + req.getCode());
        if (ObjectUtil.isNotEmpty(o)) {
            return AjaxResult.error("激活失败，请稍后再试");
        }
        if (ObjectUtil.isEmpty(req.getCode())) return AjaxResult.error("券码不能为空");
        if (ObjectUtil.isEmpty(req.getPhone())) return AjaxResult.error("手机号不能为空");

        CouponCode couponCode = couponCodeDao.lambdaQuery()
                .eq(CouponCode::getCode, req.getCode()).one();
        if (ObjectUtil.isEmpty(couponCode)) return AjaxResult.error("券码不存在");
        if (couponCode.getStartTime().getSecond() < LocalDateTime.now().getSecond())
            return AjaxResult.error("还未开放领取");
        if (couponCode.getEndTime().getSecond() < LocalDateTime.now().getSecond())
            return AjaxResult.error("券码已失效，不能领取");

        UserCouponCode userCouponCode = new UserCouponCode();
        baseDao.save(userCouponCode);
        redisTemplate.opsForValue().set("user_coupon_code_add:" + req.getCode(), 1, 600);
        return AjaxResult.success("激活成功");
    }

    @Override
    public PageList<UserCouponCodeVo> list(UserCouponCodeQuery query) {
        LambdaQueryChainWrapper<UserCouponCode> lambdaQuery = baseDao.lambdaQuery();
        if (query.getCode() != null) {
            List<Long> couponCodeIds = couponCodeDao.lambdaQuery()
                    .like(CouponCode::getCode, query.getCode())
                    .select(CouponCode::getId)
                    .list().stream()
                    .map(CouponCode::getId)
                    .collect(Collectors.toList());
            if (couponCodeIds.isEmpty()) return new PageList<>();
            lambdaQuery.in(UserCouponCode::getCouponId,couponCodeIds);
        }
        if (query.getPhone() != null) {
            List<Long> userIds = userDao.lambdaQuery().like(User::getEmail, query.getPhone())
                    .select(User::getId).list().stream().map(User::getId).collect(Collectors.toList());
            if (userIds.isEmpty()) return new PageList<>();
            lambdaQuery.in(UserCouponCode::getUserId,userIds);
        }
        if (query.getUserId() != null) lambdaQuery.eq(UserCouponCode::getUserId,query.getUserId());
        Page<UserCouponCode> page = lambdaQuery.page(new Page<>(query.getPageNum(), query.getPageSize()));
        List<UserCouponCodeVo> rowVos = new LinkedList<>();
        page.getRecords().forEach((item) -> {
            UserCouponCodeVo rowVo = modelMapper.map(item, UserCouponCodeVo.class);
            User user = userDao.getById(rowVo.getUserId());
            if (ObjectUtil.isNotEmpty(user)) {
                rowVo.setPhone(user.getEmail());
                rowVo.setUserName(user.getUsername());
            }
            CouponCode couponCode = couponCodeDao.getById(rowVo.getCouponId());
            if (ObjectUtil.isNotEmpty(couponCode)) {
                rowVo.setCode(couponCode.getCode());
            }
            rowVos.add(rowVo);
        });
        return PageList.of(rowVos, page);
    }
}
